/*
一、接口 interface
1. 名称一般以 I 开头
2. 可以描述对象， 对象属性，函数， 类; 接口中描述函数时只能是抽象， 不能有具体实现, 即不能有参数名等；
3. 可以被实现，被继承，可以使用接口继承然后再扩展各自的独立属性，
4. 多属性时使用逗号或者分号都可以
5. 可以用来描述混合类型，里面可以有函数，属性，对象等组合；
6. 多个同名接口会合并属性， 1+2=3 ， 会破坏掉原来的接口;
7. 接口支持可选属性， 仅读 readonly 属性， 使用 [xxx:string]:any   来支持任意属性的扩展， 包括 数字， Symbol 等， 最后都会自动转为 string
8. 接口可以用类来实现,类必须实现接口的全部属性，可多不可少； 一个类可以实现多个接口,用逗号分隔；  class Xxx implements Ixxx1,Ixxx2
9. 描述类的实例
10. 接口中取属性只能使用 [] 的形式；从接口中取某属性作为类型别名来使用时， 不能使用 Iii.xxx 的方式，要用 Iii['xxx'], 因为那不是命名空间



二、type
1. 不能被实现
2. 可以用来写联合类型

尽量使用接口，不能用时在用 type
 */

// 描述对象
interface IfullName {
    firstName: string,
    lastName: string,
}
// 描述函数
interface IfullName2 {
    new(name: string): any, // 描述类的实例
    (): string, // 普通函数
    speak(): void // 指定函数，如果是由类来实现，此类的原型上必须有这个同名方法， 此处使用 void 表示不关心返回值的实现，可以在具体实现时是任意返回值
}

class Cddd implements IfullName, IfullName2 {
    speak(): void {
        throw new Error('Method not implemented.');
    }
    lg(): string {
        return 'lg---------'
    }
    firstName: string = '张'
    lastName: string = '三';

}

//---------------------------------------------------------
class Person {
    constructor(public name: string) {
        this.name = name
    }
}
// 描述类的实例
interface IClass {
    new(name: string): any, // 描述类的实例
}

// 以下三种都可以作为 clazz 的类型
// { new(name: string): any }
//  new(name: string)=> any 
// IClass

function createInstance(clazz: IClass, name: string) {
    return new clazz(name)
}

let r = createInstance(Person, '张三')


//---------------------------------
interface ISchool {
    name: string,
    age: number
}
type t = ISchool['name']  // 不能写成 ISchool.name

//---------------------------------



export { }